package ExpressTwo;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.Random;

public class MainInterface extends JFrame {


    private final String[] nameOfLabel_fifo_lru = {"块号", "物理地址", "是否缺页", "是否置换", "缺页次数", "置换次数", "缺页率", "置换率"};
    private final String[] name_page = {"页号", "块号", "状态"};
    private final String[] name_stack = {"序号", "入数", "栈(底 --> 顶)", "是否缺页"};
    private final String[] name_status = {"逻辑地址", "访问次数", "页号", "页内地址", "页长", "块容量"};
    private final String[] name_btn = {"清空", "确定", "OPT算法", "退出"};

    private JPanel left_panel, center_panel, right_panel;//整体的容器
    private JButton btn_sure, btn_quit, btn_clean, btn_openOPT;

    private JTable fifo_table1, fifo_table2, lru_table1, lru_table2, bitMap_table;//表格，FIFO，LRU，位示图
    private JLabel[] labels_fifo, labels_lru, labels_status;//标签:FIFO的，LRU的，STATUES的

    //队列
    QueueList<Integer>stack_fifo;
    QueueList<Integer>stack_lru;

    QueueList<Node> list_fifo;//fifo队列
    QueueList<Node>list_lru;//lru队列

    QueueList<Integer> list_bitMapFIFO;//位示图的返回值
    QueueList<Integer>list_bitMapLRU;

    JTextField text;
    JRadioButton box1, box2;

    int pageLong;//页长
    int blockNumber;//块的数量
    int blockSize;//块大小

    int logicAddress;//逻辑地址
    int accessCount;//访问次数
    int bitCount;//位示图计数 bitCount < blockNumber
    int pageAddress;//页内地址

    int fifoNeedPage;//缺页次数
    int fifoNeedChange;//置换次数

    int lruNeedPage;//缺页次数
    int lruNeedChange;//置换次数

    //下面是opt算法的东西
    QueueList<Node>list_opt;

    MainInterface() {
        super("实验二");

        list_fifo=new QueueList<>();
        list_lru=new QueueList<>();
        list_bitMapFIFO =new QueueList<>();
        list_bitMapLRU=new QueueList<>();
        stack_fifo=new QueueList<>();
        stack_lru=new QueueList<>();

        //opt部分
        list_opt=new QueueList<>();

        //整体布局
        setLayout(new GridLayout(1, 3));

        //初始化
        initLeft();
        initCenter();
        initRight();

        initPage();
        initBitMap();


        getRootPane().setDefaultButton(btn_sure);
        //添加部件
        add(left_panel);
        add(center_panel);
        add(right_panel);

        //添加事件监听器
        btn_clean.addActionListener(new InterfaceAction(this));
        btn_sure.addActionListener(new InterfaceAction(this));
        btn_quit.addActionListener(new InterfaceAction(this));
        btn_openOPT.addActionListener(new InterfaceAction(this));

        //setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        setBounds(100, 50, 1100, 600);

    }

    private void initPage() {
        Thread thread = new Thread(() -> {
            while (true) {
                String[] str = new String[3];
                str[0] = JOptionPane.showInputDialog(this, "请输入页长(十进制)");
                if(str[0]==null|| str[0].equals(""))
                    System.exit(0);
                str[1] = JOptionPane.showInputDialog(this, "请输入块的数量(十进制)");
                if(str[1]==null|| str[1].equals(""))
                    System.exit(0);
                str[2] = JOptionPane.showInputDialog(this, "请输入块的大小(kb)(十进制)");
                if(str[2]==null|| str[2].equals(""))
                    System.exit(0);
                try {
                    pageLong = Integer.parseInt(str[0]);
                    blockNumber = Integer.parseInt(str[1]);
                    blockSize = Integer.parseInt(str[2]);
                    labels_status[4].setText(String.valueOf(pageLong));
                    labels_status[5].setText(blockNumber + " * " + blockSize + " (kb)");
                    break;
                } catch (Exception e) {
                    JOptionPane.showMessageDialog(null,
                            "输入有误",
                            "错误",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
            initFIFO();//初始化表格
            initLRU();//初始化表格
        });
        thread.start();
    }

    private void initBitMap() {
        int[] bit = new int[bitMap_table.getColumnCount() * bitMap_table.getRowCount()];
        Random random = new Random();

        for (int i = 0; i < bit.length; i++) {
            bit[i] = random.nextInt() % 2;
            if (bit[i] < 0)
                bit[i] = -bit[i];
        }
        for (int i = 0; i < bitMap_table.getColumnCount(); i++) {
            for (int j = 0; j < bitMap_table.getRowCount(); j++) {
                bitMap_table.setValueAt(String.valueOf(bit[i * bitMap_table.getColumnCount() + j]), i, j);
            }
        }
    }

    private void initFIFO() {
        DefaultTableModel d = (DefaultTableModel) fifo_table1.getModel();
        for (int i = 0; i < pageLong; i++) {
            d.addRow(new String[]{String.valueOf(i), "", "0"});
        }
    }

    private void initLRU() {
        DefaultTableModel d = (DefaultTableModel) lru_table1.getModel();
        for (int i = 0; i < pageLong; i++) {
            d.addRow(new String[]{String.valueOf(i), "", "0"});
        }
    }

    private void initLeft() {
        left_panel = new JPanel(new GridLayout(2, 1));

        JPanel fifo_panel = new JPanel(new GridLayout(1, 2));
        //左边的容器
        JPanel lru_panel = new JPanel(new GridLayout(1, 2));
        JPanel fifo_left_panel = new JPanel(new GridLayout(4, 2));
        JPanel lru_left_panel = new JPanel(new GridLayout(4, 2));

        labels_fifo = new JLabel[8];
        labels_lru = new JLabel[8];

        for (int i = 0; i < labels_fifo.length; i++) {
            //fifo的标签
            labels_fifo[i] = new JLabel("null");
            labels_fifo[i].setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), nameOfLabel_fifo_lru[i]));

            //lru的标签
            labels_lru[i] = new JLabel("null");
            labels_lru[i].setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), nameOfLabel_fifo_lru[i]));

            //设置字体
            labels_fifo[i].setFont(new Font("宋体", Font.BOLD, 15));
            labels_lru[i].setFont(new Font("宋体", Font.BOLD, 15));

            //添加到容器
            fifo_left_panel.add(labels_fifo[i]);
            lru_left_panel.add(labels_lru[i]);
        }

        DefaultTableModel d;//默认表容器
        fifo_table1 = new JTable();//左边的表1
        lru_table1 = new JTable();//左边的表2

        d = (DefaultTableModel) fifo_table1.getModel();
        d.setColumnIdentifiers(name_page);//设置图号，左边的图

        d = (DefaultTableModel) lru_table1.getModel();
        d.setColumnIdentifiers(name_page);
        JScrollPane scroll1 = new JScrollPane(fifo_table1);
        JScrollPane scroll2 = new JScrollPane(lru_table1);

        fifo_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "先进先出(FIFO)"));
        fifo_panel.add(fifo_left_panel);
        fifo_panel.add(scroll1);

        lru_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "最近最久未使用(LRU)"));
        lru_panel.add(lru_left_panel);
        lru_panel.add(scroll2);

        left_panel.add(fifo_panel);
        left_panel.add(lru_panel);
    }

    private void initCenter() {
        DefaultTableModel d;
        center_panel = new JPanel(new GridLayout(2, 1));
        JPanel fifo_center_panel = new JPanel(new GridLayout(1, 1));
        JPanel lru_center_panel = new JPanel(new GridLayout(1, 1));

        fifo_table2 = new JTable();
        lru_table2 = new JTable();
        fifo_center_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "先进先出置换流程"));
        lru_center_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "最近最久未使用置换流程"));

        d = (DefaultTableModel) fifo_table2.getModel();
        d.setColumnIdentifiers(name_stack);
        d = (DefaultTableModel) lru_table2.getModel();
        d.setColumnIdentifiers(name_stack);

        JScrollPane scroll1 = new JScrollPane(fifo_table2);
        JScrollPane scroll2 = new JScrollPane(lru_table2);

        fifo_center_panel.add(scroll1);
        lru_center_panel.add(scroll2);

        center_panel.add(fifo_center_panel);
        center_panel.add(lru_center_panel);

    }

    private void initRight() {
        bitMap_table = new JTable(8, 8);
        bitMap_table.setEnabled(false);
        //bitMap_table.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),"位示图"));
        JPanel right_top_panel = new JPanel(new GridLayout(1, 1));
        JPanel right_center_panel = new JPanel(new GridLayout(1, 1));

        JPanel right_center_top_panel = new JPanel(new GridLayout(3, 2));
        JPanel right_center_bottom_panel = new JPanel();

        //右边的容器

        right_panel = new JPanel(new GridLayout(3, 1));

        labels_status = new JLabel[6];

        text = new JTextField();
        text.setColumns(10);
        btn_clean = new JButton(name_btn[0]);
        btn_sure = new JButton(name_btn[1]);
        btn_openOPT = new JButton(name_btn[2]);

        btn_quit = new JButton(name_btn[3]);

        right_top_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "位示图"));

        right_top_panel.add(new JScrollPane(bitMap_table));


        right_center_bottom_panel.add(text);
        right_center_bottom_panel.add(btn_clean);
        right_center_bottom_panel.add(btn_sure);

        //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
        JPanel center = new JPanel(new GridLayout(3, 1));
        JPanel p1 = new JPanel(new GridLayout(1, 2));
        JPanel p2 = new JPanel(new GridLayout(1, 2));
        box1 = new JRadioButton("十六进制");
        box2 = new JRadioButton("十进制");
        p2.add(text);
        text.setFont(new Font("宋体", Font.BOLD, 24));
        p2.add(btn_clean);
        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(box1);
        buttonGroup.add(box2);
        box1.setSelected(true);
        p1.add(box1);
        p1.add(box2);
        center.setBorder(BorderFactory.createEtchedBorder());
        center.add(p2);
        center.add(p1);
        center.add(btn_sure);

        //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$4

        for (int i = 0; i < labels_status.length; i++) {
            labels_status[i] = new JLabel("null");
            labels_status[i].setFont(new Font("宋体", Font.BOLD, 15));
            labels_status[i].setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), name_status[i]));
            right_center_top_panel.add(labels_status[i]);
        }

        right_center_panel.add(right_center_top_panel);
        JPanel right_bottom_panel = new JPanel(new GridLayout(1, 2));
        right_bottom_panel.add(center);
        right_bottom_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "输入"));
        right_bottom_panel.add(center);

        //###############################

        JPanel p4 = new JPanel(new GridLayout(2, 1));
        p4.setBorder(BorderFactory.createEtchedBorder());
        p4.add(btn_openOPT);
        p4.add(btn_quit);

        right_bottom_panel.add(p4);

        //###############################

        //三部分
        right_panel.add(right_top_panel);
        right_panel.add(right_center_panel);
        right_panel.add(right_bottom_panel);
    }


    //这是更改标签部分
    //设置FIFO的标签，左上角
    void setLabels_fifo(int index, String value) {
        if (index < labels_fifo.length)
            labels_fifo[index].setText(value);
    }

    //设置LRU的标签，左下角
    void setLabels_lru(int index, String value) {
        if (index < labels_lru.length)
            labels_lru[index].setText(value);
    }

    //这是更改状态部分
    //设置状态的标签，右方
    void setLabels_status(int index, String value) {
        if (index < labels_status.length)
            labels_status[index].setText(value);
    }

    JTable getFifo_table1() {
        return fifo_table1;
    }

    JTable getFifo_table2() {
        return fifo_table2;
    }

    JTable getLru_table1() {
        return lru_table1;
    }

    JTable getLru_table2() {
        return lru_table2;
    }

    JTable getBitMap_table() {
        return bitMap_table;
    }

    public static void main(String[] args) {
        //主函数
        new MainInterface();
    }
}
